/**
 * @file    main.c 
 * @author  18408107475@163.com
 * @version V1.0.0
 * @date    2025-07-13
 * @brief   基于编码器的转速测量系统
 * @details 
 * 硬件配置：
 *   - 主控芯片：STM32F10x系列（如STM32F103C8T6）
 *   - 编码器：正交编码器（A相→PC6，B相→PC7）
 *   - 定时器：TIM8（编码器接口模式）、TIM4（定时中断，5Hz频率）
 *   - 显示设备：OLED SSD1315（128x64，I2C接口）
 * 
 * 软件特性：
 *   - 定时（200ms间隔）读取编码器脉冲变化量
 *   - 通过OLED实时显示转速（脉冲数/200ms）
 *   - 利用TIM4中断实现周期性测量，主循环仅负责显示
 */

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"              // STM32标准外设库（提供所有外设寄存器定义）
#include "Delay.h"                  // 基于SysTick的延时函数（本程序未直接使用）
#include "USART1_Config.h"          // USART1配置（备用调试接口，未启用）
#include "OLED_SSD1315_Config.h"    // OLED驱动库（用于显示转速）
#include "TIM_Config.h"             // TIM4定时器配置（提供定时中断）
#include "ENCODER_Config.h"         // 编码器配置（基于TIM8的正交解码）


/* 私有变量定义 --------------------------------------------------------------*/
int16_t Speed = 0;  // 存储编码器转速（脉冲变化量/200ms，正值正转，负值反转）


/**
 * @brief  主程序入口
 * @param  None
 * @retval int 程序状态码（实际不返回，因主循环为无限循环）
 * @执行流程：
 *   1. 初始化TIM4定时器（5Hz中断频率，即200ms中断一次）
 *   2. 初始化编码器（TIM8正交模式，检测PC6/PC7脉冲）
 *   3. 初始化OLED并清屏，显示固定文本框架
 *   4. 进入主循环：实时显示Speed变量的值
 */
int main(void)
{
    // 初始化TIM4：中断频率=Freq_Down/Freq_Up=5/1=5Hz（周期200ms）
    TIM4_Config(1, 5);

    // 初始化编码器：配置PC6/PC7为上拉输入，TIM8为编码器模式
    Encoder_Config();
    
    // 初始化OLED显示屏（I2C通信，128x64分辨率）
    OLED_SSD1315_Init();       

    // 清屏：清除OLED显存，初始化显示界面
    OLED_SSD1315_Clear();       
    
    // 在OLED第0行显示固定文本"Speed: "（字体16x16，左对齐）
    OLED_SSD1315_ShowString(0,0, "Speed: ", 16, false); 

    // 无限循环：持续刷新OLED显示（显示当前Speed值）
    while (1)                   
    {
        // 在第0行、第49列（"Speed: "后）显示Speed值（5位数字，字体16x16）
        OLED_SSD1315_ShowNum(49,0, Speed, 5, 16);
    }
}

/**
 * @brief  TIM4中断服务函数（每200ms执行一次）
 * @param  无
 * @retval 无
 * @执行流程：
 *   1. 检查中断源是否为TIM4更新事件（溢出）
 *   2. 读取编码器脉冲变化量（过去200ms内的相对位移）
 *   3. 清除中断标志位，准备下次中断
 * @核心功能：
 *   - 定时更新Speed变量，反映编码器的转速（脉冲数/200ms）
 */
void TIM4_IRQHandler(void)
{
    // 检查中断源是否为TIM4更新事件（计数器溢出）
    if (TIM_GetITStatus(TIM4, TIM_IT_Update)) {
        
        // 读取过去200ms内的编码器脉冲变化量（正转正值，反转负值）
        Speed = Encoder_GetSpeed();
        
        // 清除中断标志位（写1清零，避免重复触发）
        TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
    }
}


/************************ (C) COPYRIGHT 2025 TS *****END OF FILE****/
